﻿package yii{

	import flash.display.*;
	import flash.utils.*;
	import yii.base.*;
	import yii.db.*;
	import yii.db.ar.*;
	import yii.db.schema.*;
	import yii.db.schema.sqlite.*;
	import phpas3.*;

	public class Yii{

	// original
	public static var classMap:Array = new Array();
	public static var enableIncludePath:Boolean = true;
	//private static var _aliases = new Array('system'=>YII_PATH,'zii'=>YII_ZII_PATH); // alias => path
	private static var _imports = new Array();					// alias => class name or directory
	private static var _includePaths;						// list of include paths
	private static var _app:CApplication;
	private static var _logger;

	// custom
	static public var showLog_bool:Boolean = false;



	/**
	 * Stores the application instance in the class static member+
	 * This method helps implement a singleton pattern for CApplication+
	 * Repeated invocation of this method or the CApplication constructor
	 * will cause the throw of an exception+
	 * To retrieve the application instance, use {@link app()}+
	 * @param CApplication $app the application instance+ If this is null, the existing
	 * application singleton will be removed+
	 * @throws CException if multiple application instances are registered+
	 */
	public static function setApplication($app):void{
		if(_app===null || $app===null)
			_app = $app;
		else
			throw new Error( "Yii application can only be created once" );
	}


	/**
	 * Creates an application of the specified class+
	 * @param string $class the application class name
	 * @param mixed $config application configuration+ This parameter will be passed as the parameter
	 * to the constructor of the application class+
	 * @return mixed the application instance
	 * @since 1+0+10
	 */
	public static function createApplication($config:Object=null):CApplication{
		count(1);
		return new CApplication( $config );
	}






	/**
	 * Creates an object and initializes it based on the given configuration+
	 *
	 * The specified configuration can be either a string or an array+
	 * If the former, the string is treated as the object type which can
	 * be either the class name or {@link YiiBase::getPathOfAlias class path alias}+
	 * If the latter, the 'class' element is treated as the object type,
	 * and the rest name-value pairs in the array are used to initialize
	 * the corresponding object properties+
	 *
	 * Any additional parameters passed to this method will be
	 * passed to the constructor of the object being created+
	 *
	 * NOTE: the array-typed configuration has been supported since version 1+0+1+
	 *
	 * @param mixed $config the configuration+ It can be either a string or an array+
	 * @return mixed the created object
	 * @throws CException if the configuration does not have a 'class' element+
	 */
	public static function createComponent( $config:*, ...$args:Array ):*{
		//Yii.log( "$config="+ $config );
		// クラスプリロード
		CSqliteSchema;
		CDbConnection;

		var $type:Class;
		if( is_string($config) ){
			$type = getDefinitionByName($config) as Class;
			$config = new Array();
		} else if(isset($config['class'])){
			$type = getDefinitionByName($config['class']) as Class;
			delete $config['class'];
		} else {
			throw new Error( "Object configuration must be an array containing a class element" );
		}

//		if( !class_exists($type,false) ){
//			$type = Yii::import( $type,true );
//		}

		$args.unshift( $config );// phpと合わせるために、先頭にダミーの要素を追加
		var $n:int = $args.length;
		var $object;
		if( $n > 1 ){
			if( $n===2 ){
				$object = new $type( $args[1] );
			} else if($n===3){
				$object = new $type( $args[1], $args[2] );
			} else if( $n===4 ){
				$object = new $type( $args[1], $args[2], $args[3] );
			}
		} else {
			$object = new $type();
		}

		for( var $key in $config ){
			var $value = $config[$key];
			$object[$key] = $value;
		}

		return $object;
	}






	public static function app():CApplication{
		return _app;
	}

	public static function log(...args:Array){
		if( showLog_bool ){
			var e:Error = new Error();
			var s:String = e.getStackTrace();
			if( s ){
				var ary:Array = s.split( "\n" );
				trace( args, ary[2] );
			} else {
				trace( args );
			}
		}
	}

	public static function showStackTrace( message:String="" ):void{
		var e:Error = new Error();
		var s:String = e.getStackTrace();
		if( s ){
			var ary:Array = s.split( "\n" );
			ary.splice( 0, 2 );
			trace( message, ary.join("\n") );
		}
	}

//		static public function createComponent( config:*, ...args:Array ):*{
//			// クラスプリロード
//			CSqliteSchema;
//
//			if( typeof(config)=="string" ){
//				var myClass:Class = getDefinitionByName(config) as Class;
//				switch( args.length ){
//					case 0:
//						return new myClass();
//						break;
//					case 1:
//						return new myClass( args[0] );
//						break;
//					case 2:
//						return new myClass( args[0], args[1] );
//						break;
//				}
//
//			}
//		}


	}
}